
#include "module_program.h"


//Function pointer to running program
Program *_progs[MAXPROGS];




int8_t module_program_init(void)
{
	#ifdef DEBUG
	usart_writeln("Initializing module Program...");
	#endif
	
	/* Max length for name is 15 chars! */
	strncpy(prog_menu.name, "prog_menu",15);
	prog_menu.writeslcd = 1;
	prog_menu.initfunc = prog_menu_init;
	prog_menu.uninitfunc = prog_menu_uninit;
	prog_menu.runfunc = prog_menu_run;
	
	
	
	/* Max length for name is 15 chars! */
	strncpy(prog_trigger.name,"prog_trigger",15);
	prog_trigger.writeslcd = 0;
	prog_trigger.initfunc = prog_trigger_init;
	prog_trigger.uninitfunc = prog_trigger_uninit;
	prog_trigger.runfunc = prog_trigger_run;
	
	/* Max length for name is 15 chars! */
	strncpy(prog_io_debug.name,"prog_io_debug",15);
	prog_io_debug.writeslcd = 1;
	prog_io_debug.initfunc = prog_io_debug_init;
	prog_io_debug.uninitfunc = prog_io_debug_uninit;
	prog_io_debug.runfunc = prog_io_debug_run;
	
	/* Max length for name is 15 chars! */
	strcpy(prog_usartmenu.name,"prog_usartmenu");
	prog_usartmenu.writeslcd = 0;
	prog_usartmenu.initfunc = prog_usartmenu_init;
	prog_usartmenu.uninitfunc = prog_usartmenu_uninit;
	prog_usartmenu.runfunc = prog_usartmenu_run;
	
	/* Max length for name is 15 chars! */
	strcpy(prog_manual_control.name,"prog_manual_ct");
	prog_manual_control.writeslcd = 1;
	prog_manual_control.initfunc = prog_manual_control_init;
	prog_manual_control.uninitfunc = prog_manual_control_uninit;
	prog_manual_control.runfunc = prog_manual_control_run;
	
	#ifdef DEBUG
	usart_writeln("module Program initialized.OK");
	
	#endif
	return 1;
}
int8_t module_program_run(void)
{
	uint8_t i=0, ret=0;
	for(i=0;i< MAXPROGS;i++)
	{
		if(_progs[i] != NULL)
		{
			ret = _progs[i]->runfunc();
			if(!ret)
			{
				usart_write("Error returned while running ");
				usart_writeln(_progs[i]->name);
			}
		}
	}

	return 1;
}

int8_t prog_is_running(Program *prog)
{
	int8_t i;
	for(i=0;i<MAXPROGS;i++)
	{
		if(_progs[i] == prog)
		{
			return 1;
		}
	}
	return 0;
}

int8_t add_prog(Program *prog)
{
	#ifdef DEBUG
	usart_write("* Adding program ");
	usart_write(prog->name);
	usart_write("...");
	#endif
	
	int8_t progadded=0;
	int8_t i;
	for(i=0;i<MAXPROGS;i++)
	{
		if(_progs[i] == NULL)
		{
			_progs[i] = prog;
			progadded = 1;
			break;
		}
	}
	if(progadded)
	{
		#ifdef DEBUG
		usart_writeln("OK");
		#endif
		prog->initfunc();
	}else
	{
		#ifdef DEBUG
		usart_writeln("ERROR, program queue is full");
		#endif
	}
		
	return progadded; //In essence True / False 
}

int8_t remove_prog(Program *prog)
{
	#ifdef DEBUG
	usart_write("* Removing program ");
	usart_write(prog->name);
	usart_write("...");
	#endif
	int8_t i;
	for(i=0;i<MAXPROGS;i++)
	{
		if(_progs[i] == prog)
		{
			prog->uninitfunc();
			_progs[i] = NULL;
			#ifdef DEBUG
			usart_writeln("OK");
			#endif
			return 1;
		}
	}
	#ifdef DEBUG
	usart_writeln("ERROR, program not found!");
	#endif
	return 0;
	
}

void remove_lcdwriting_progs(void)
{
	int8_t i;
	for(i=0;i<MAXPROGS;i++)
	{
		if(_progs[i] && _progs[i]->writeslcd == 1)
		{
			remove_prog(_progs[i]);
		}
	}
}

void progs_running(void)
{
	int8_t i;
	char *temp = (char *) malloc(sizeof(char)*50);
	usart_writeln(txt_separator_line);
	usart_writeln("Running programs:");
	for(i=0;i<MAXPROGS;i++)
	{
		sprintf(temp, "%i: ", i);
		usart_write(temp);
		usart_write(_progs[i]->name);
		sprintf(temp, " (0x%x)", (unsigned int) _progs[i]->runfunc);
		usart_writeln(temp);
	}
	free(temp);
	usart_writeln(txt_separator_line);
}
